-
Notifications
You must be signed in to change notification settings - Fork 8k
Bluetooth: Host: Add role-specific auto PHY update options #97198
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
c33aaac
to
b93d436
Compare
Posting here the latest from Discord: There shouldn't be a need for any of this automation in the host, neither for the PHY nor for the data length, due to the existence of Actually, we already have The only place where the |
Conclusion from the Bluetooth WG meeting: The set_default HCI commands don't actually cause any procedures to be triggered in themselves, so the explicit triggering by the host still has a purpose. I'll therefore roll back to my earlier plan to just do the role split for the phy update. For data length, we can either remove or deprecate the "auto" Kconfig option, since it serves no purpose now that the controller "no_auto_dle" quirk comes from DTS, i.e. is build-time resolvable in itself. Another improvement that can be done (follow-up PR) is to cache the controller max data length, since we read it already during HCI init, i.e. no need to redo this for every connection. |
Just re-iterating my statements from the WG meeting.
Agree. And keep the feature available (default disabled is ok) for users needing auto PHY update being handled by Host on connection establishment (i.e. while
Agree.
Agree. |
HCI spec does not prohibit asking for a larger value than the Controller supports. We can always do |
From 7.8.33 LE Set Data Length command (similar text exists for 7.8.35 LE Write Suggested Default Data Length command):
I think that make might sense to do. We probably want to use the largest data length, and since the host isn't using the results of |
b93d436
to
d6b78bb
Compare
subsys/bluetooth/host/conn.c
Outdated
switch (conn->role) { | ||
#if defined(AUTO_PHY_CENTRAL) | ||
case BT_HCI_ROLE_CENTRAL: | ||
if (AUTO_PHY_CENTRAL_SUPPORTED(bt_dev.le.features) && | ||
phy_change_needed(conn, AUTO_PHY_CENTRAL)) { | ||
err = bt_le_set_phy(conn, 0U, AUTO_PHY_CENTRAL_PREF, | ||
AUTO_PHY_CENTRAL_PREF, BT_HCI_LE_PHY_CODED_ANY); | ||
} | ||
if (conn->state != BT_CONN_CONNECTED) { | ||
return; | ||
break; | ||
#endif | ||
#if defined(AUTO_PHY_PERIPHERAL) | ||
case BT_HCI_ROLE_PERIPHERAL: | ||
if (AUTO_PHY_PERIPHERAL_SUPPORTED(bt_dev.le.features) && | ||
phy_change_needed(conn, AUTO_PHY_PERIPHERAL)) { | ||
err = bt_le_set_phy(conn, 0U, AUTO_PHY_PERIPHERAL_PREF, | ||
AUTO_PHY_PERIPHERAL_PREF, BT_HCI_LE_PHY_CODED_ANY); | ||
} | ||
break; | ||
#endif | ||
default: | ||
/* No PHY preferences set for the given role */ | ||
break; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that phy_change_needed
takes conn
, the conn->role
check could be moved to that function which would make the code here significantly simpler
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm all for finding ways to simplify this. However, I'm not sure how that exact proposal helps, since we also need the role to know what to pass to the bt_le_set_phy()
call.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since we also need the role to know what to pass to the bt_le_set_phy() call.
Since the value is exclusively based on the conn->role
, then we don't need to pass it along at all. The function can just take the conn
pointer and nothing more :)
subsys/bluetooth/host/conn.c
Outdated
*/ | ||
static bool uses_symmetric_2mbit_phy(struct bt_conn *conn) | ||
#if defined(AUTO_PHY_CENTRAL) || defined(AUTO_PHY_PERIPHERAL) | ||
static bool phy_change_needed(struct bt_conn *conn, uint8_t phy) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor: "Needed" is a bit strongly worded here; we never really need to update the PHY, do we?
(Not a blocker, and the name is OK, but otherwise consider can_update_phy
or something instead?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure "can" is any more intuitive here. This is whether we already have the PHY we prefer. If we do, then we don't "need" to do the procedure. What other word would be better?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we end up moving everything related to the PHY update into the function (see #97198 (comment)), it would probably just be do_auto_phy_update
:D
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I can certainly refactor this so that everything is in a single PHY-related function. It might have a slight impact on code size, but likely not much (if any)
subsys/bluetooth/host/Kconfig
Outdated
config BT_AUTO_PHY_PERIPHERAL_NONE | ||
bool "No PHY preference" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would consider putting "None" as the first choice
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Btw, the _NONE options shouldn't really be needed since Kconfig has the optional
keyword for choice
statements which make it possible to not have any of the possible options selected. The problem with optional
(as I discovered) is that it then doesn't allow us to have a default where one of the options would anyway be selected. The only effect of a default for optional
is that when you select the choice on the top-level in menuconfig, then the default is what'll be initially enabled, however the top-level doesn't implicitly get enabled by specifying a default.
d6b78bb
to
cc810c8
Compare
There's a regression from commit 8cfad44 which introduced trying to enable advertising twice. Remove the other attempt. Signed-off-by: Johan Hedberg <[email protected]>
The BT_AUTO_PHY_UPDATE option was problematic in the sense that it didn't really allow any kind of fine-tuning of what automation is desired. In particular, it didn't allow specifying which PHY was the preferred one (it was hardcoded to 2M) and also didn't allow specifying role-specific (central vs peripheral) preferences. To solve this, deprecate the old option, and instead introduce role-specific options that allow specifying 1M/2M/Coded/None as the preference. The new options have slightly different defaults than the new: for central role 2M stays as the preference, however since it's uncommon to require automated changes on the peripheral side the default is set to None there. Signed-off-by: Johan Hedberg <[email protected]>
Document the changes related to Bluetooth auto PHY update Kconfig options. Signed-off-by: Johan Hedberg <[email protected]>
Remove deprecated Kconfig option usage, and replace it with corresponding options which yield the same behavior as before. Signed-off-by: Johan Hedberg <[email protected]>
Make sure to consider both the new peripheral and central Kconfig options when calculating needed TX buffers. Signed-off-by: Johan Hedberg <[email protected]>
6b578db
to
dff2e4c
Compare
I'd say that would be nicer. Otherwise the next thing would be someone looking at one libc errno.h or another and getting confused. Just faster to see the error name printed. |
Turns out this was a red herring :( It was a bug, but not the cause of the test case failure. Only other idea I have is to 100% restore the PHY config for this test case, in case it depends on both sides to have "auto-phy 2M" enabled. |
Now we have
|
I also get that for #91587. Sometimes it helps nudging the |
@Thalley that should not be happening unless there is unitialized memory in play (or the test is killed in CI due to taking too long). |
I've seen that happen on many occasions over the years, and I've never been able to find any memory issues with valgrind, ASAN or UBSAN :) |
@Thalley why hasn't the test been at least disabled, if a proper fix is not known? Blocking other PRs is justification enough to treat fixing or disabling it as a hotfix. I can disable as part of this PR, or would you like to do it separately? |
This PR changes the default timeline of many tests, causing scheduling overlaps or change in connection event length. Restoring back the use of PHY update for the failing tests should make it pass, have you tried that? |
I haven't, since @Thalley pointed out that the same test is also failing for #91587 (which doesn't change any timings, AFAIK) |
Because it's not specific to this test. This behavior/issue can somewhat randomly happen to any test (and especially any LE Audio test, given that we are often doing quite a lot on air in those tests with multiple devices).
The PR here does change the timing, since it removes a few steps in a function. The real problem is, IMO, the scheduling overlaps that isn't being handled well. In a real-world device, it would/should probably do a retry if it fails to sync to the PA or any similar issue (often triggered by a user interaction), but that isn't the case with the tests today. |
Restore the auto-phy config for tests which seem particularly sensitive to timings related to this. Signed-off-by: Johan Hedberg <[email protected]>
646596c
to
f170248
Compare
Just pushed an update not to modify the auto-phy stuff for the audio bsim tests. |
|
err = bt_le_adv_start(BT_LE_ADV_CONN_FAST_1, ad, ARRAY_SIZE(ad), NULL, 0); | ||
if (err) { | ||
FAIL("Advertising failed to start (err %d)\n", err); | ||
return; | ||
} | ||
|
||
err = start_advertising(); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar change but retains FAIL
in the test in this PR: #97479
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test code seems to use printk()
and FAIL()
kind of interchangeably. E.g. don't you get duplicated output with your PR since start_advertising()
has an internal printk()
for the failure case?
Uh oh!
There was an error while loading. Please reload this page.